package com.stress.testing.common.plugin;

import com.stress.testing.common.AgentContext;
import com.stress.testing.common.conf.DefaultPluginConfigLoader;
import com.stress.testing.common.conf.PluginConfig;
import com.stress.testing.common.conf.PluginConfigLoader;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

public class DefaultPluginLoader implements PluginLoader {
    @Override
    public List<PluginContext> load(AgentContext context) {
        Map<String, List<URL>> agentPluginURL = context.getAgentPluginURL();
        List<PluginContext> pluginContexts = new ArrayList<>(agentPluginURL.values().size());

        for (Map.Entry<String, List<URL>> entry : agentPluginURL.entrySet()) {
            String pluginName = entry.getKey();
            List<URL> urls = entry.getValue();

            // 习惯上，一个pluginName中包含一个jar
            for (URL url : urls) {
                // 加载配置
                PluginConfigLoader pluginConfigLoader = new DefaultPluginConfigLoader();
                String pluginPath = context.getAgentPluginPath() + File.separator + pluginName;
                PluginConfig pluginConfig = pluginConfigLoader.load(pluginPath);
                /*if(!pluginConfig.enable()){
                    continue;
                }*/

                // 构造plugin classloader
                PluginClassLoader pluginClassLoader = new PluginClassLoader(new URL[]{url},
                        context.getAgentExtendJarClassLoader());

                // spi加载plugin
                ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, pluginClassLoader);
                Iterator<Plugin> iterator = serviceLoader.iterator();

                // 习惯上一个jar中一个plugin
                while (iterator.hasNext()) {
                    Plugin plugin = iterator.next();
                    plugin.init(context.getAgentConfig(), pluginConfig);
                    PluginContext pluginContext = new DefaultPluginContext(pluginName, plugin, url, pluginClassLoader);
                    pluginContexts.add(pluginContext);
                }

            }
        }

        return pluginContexts;
    }
}
